#include <iostream>
#include "simulator/tools/bitTools.h"
#include "dspSimulator/dspSimulator/dspSimulator.h"

using namespace dspsimulator;
using namespace simulator;

int main() {
    auto dsp_machine = std::make_shared<DspMachine>();
    std::shared_ptr<LLVMJit> llvmJit = std::make_shared<LLVMJit>();
    const char *filePath = "/home/zengao/Desktop/dsp-sim/for.out";
    std::shared_ptr<simulator::ELF32Loader> elfLoader = std::make_shared<simulator::ELF32Loader>(filePath);

    auto dsp_simulator = std::make_shared<dspsimulator::DSPSimulator>(dsp_machine, llvmJit, elfLoader);

    std::string pc_name = get_reg_name(dspsimulator::RegKind::PC);
    u32 pc = 0x85A0;

    dsp_machine->registers()->get_reg32(pc_name)->set_data(pc);
    auto memory = dsp_machine->mmu()->memory();
    // 0426 MVK .L1  0,A0
    {
        std::vector<u8> mvk = {0x26, 0x04};
        memory->write(mvk, pc);
        pc += 2;
    }
    // 2426 MVK .L1  1,A0
//    {
//        std::vector<u8> mvk = {0x26, 0x24};
//        memory->write(mvk, pc);
//        pc += 2;
//    }
    // 0427 MVk .L2 0, B0
    {
        std::vector<u8> mvk = {0x27, 0x04};
        memory->write(mvk, pc);
        pc += 2;
    }
    // 068013A2 MVC .S2X A0,ILC
    {
        std::vector<u8> mvc = {0xa2, 0x13, 0x80, 0x06};
        memory->write(mvc, pc);
        pc += 4;
    }
    // 4C6E NOP 3
    {
        std::vector<u8> nop = {0x6E, 0x4C};
        memory->write(nop, pc);
        pc += 2;
    }
    // 0D66 SPLOOP 3
    {
        std::vector<u8> sploop = {0x66, 0x0d};
        memory->write(sploop, pc);
        pc += 2;
    }
    // B876 ADD .D1 A0,1,A0
    {
        std::vector<u8> add = {0x76, 0xB8};
        memory->write(add, pc);
        pc += 2;
    }
    // 0c6E NOP 1
    {
        std::vector<u8> nop = {0x6e, 0x0c};
        memory->write(nop, pc);
        pc += 2;
    }
    // 2C67 SPMASK L1
    {
        std::vector<u8> spmask = {0x67, 0x2c};
        memory->write(spmask, pc);
        pc += 2;
    }
    // 2430 ADD .L1 A0,1,A3
    {
        std::vector<u8> add = {0x30, 0x24};
        memory->write(add, pc);
        pc += 2;
    }
    // 1C66 SPKERNEL 0, 0
    {
        std::vector<u8> spkernel = {0x66, 0x1c};
        memory->write(spkernel, pc);
        pc += 2;
    }
    // 2401 ADD .L2 B0,1,B0
    {
        std::vector<u8> add = {0x01, 0x24};
        memory->write(add, pc);
        pc += 2;
    }
    // B877 ADD .D2 B0,1,B0
    {
        std::vector<u8> add = {0x77, 0xB8};
        memory->write(add, pc);
        pc += 2;
    }
    // 0c6e NOP
    {
        std::vector<u8> nop = {0x6e, 0x0c};
        memory->write(nop, pc);
        pc += 2;
    }
    // EFA00500 fphead
    {
        std::vector<u8> fphead = {0x00, 0x05, 0xa0, 0xef};
        memory->write(fphead, pc);
        pc += 4;
    }
    dsp_simulator->run();
}